package me.zhengjie.modules.docparse.parse;

import me.zhengjie.modules.docparse.domain.dto.FileDto;
import me.zhengjie.modules.docparse.domain.vo.StructablePptVo;
import org.apache.poi.hslf.extractor.PowerPointExtractor;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
import org.apache.poi.xslf.usermodel.*;
import org.apache.xmlbeans.XmlException;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;
import java.util.regex.Pattern;


@me.zhengjie.modules.docparse.annotation.Parser(fileType = {"ppt", "pptx"})
public class PptParser implements Parser<StructablePptVo> {


    @Override
    public StructablePptVo parse(String path) {
        String text = parseToString(path);
        StructablePptVo pptVo = new StructablePptVo();
        pptVo.setContent(text);
        pptVo.setTitles(parseToTitles(path));
        return pptVo;
    }

    @Override
    public StructablePptVo parse(FileDto fileDto) {
        StructablePptVo vo = new StructablePptVo();
        String text = parseToString(fileDto.getInputStream());
        vo.setContent(text);
        return vo;
    }

    /***
     * 获取PPT和PPTX的文档内容
     * @param filePath ppt路径
     * @return
     */
    @Override
    public String parseToString(String filePath) {
        File f = new File(filePath);
        String text = "";
        try {
            if (f.getName().matches(".*\\.ppt$")) {
                return ppt2String(f);
            }
            if (f.getName().matches(".*\\.pptx$")) {
                return pptx2String(filePath);
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "error";
        } catch (XmlException e) {
            e.printStackTrace();
        } catch (OpenXML4JException e) {
            e.printStackTrace();
        }
        return text;
    }

    /***
     * 获取PPT和PPTX的标题
     * @param filePath
     * @return
     */
    public String parseToTitles(String filePath) {
        String text = "";
        try {
            if (filePath.endsWith(".ppt")) {
                return getPptTitles(filePath);
            }
            if (filePath.endsWith(".pptx")) {
                return getPptxTitles(filePath);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "error";
        }
        return text;
    }

    public String ppt2String(File file) throws IOException {
        try {
            FileInputStream fis = new FileInputStream(file);
            PowerPointExtractor extractor = new PowerPointExtractor(fis);
            String str = extractor.getText();
            extractor.close();
            return str;
        } catch (Exception e) {
            return "";
        }

    }

    public String pptx2String(String path) throws IOException, OpenXML4JException, XmlException {
        try {
            return new XSLFPowerPointExtractor(POIXMLDocument.openPackage(path)).getText();
        } catch (Exception e) {
            return "";
        }

    }

    public String getPptTitles(String path) throws IOException {

        try {
            FileInputStream is = new FileInputStream(path);
            ZipSecureFile.setMinInflateRatio(-1.0d);
            HSLFSlideShow ppt = new HSLFSlideShow(is);
            is.close();
            String pptTitle = "";
            int flag = 0;
            List<HSLFSlide> slides = ppt.getSlides();
            for (HSLFSlide slide : slides) {

                //如果幻灯片中设置了标题
                if (slide.getTitle() != null && !slide.getTitle().replace(" ", "").replace("\n", "").replace("\r\n", "").equals("") && slide.getTitle().length() <= 30 && slide.getTitle().length() > 1) {
                    pptTitle = pptTitle + slide.getTitle().replace(" ", "").replace("\n", "").replace("\r\n", "") + "......" + slide.getSlideName() + "\n";
                } else {
                    //如果幻灯片中没有设置标题，则获取每页中的第一个文本块，提出空文本和数字文本
                    List<List<HSLFTextParagraph>> textParagraphs = slide.getTextParagraphs();
                    for (List<HSLFTextParagraph> paragraphs : textParagraphs) {
                        if (paragraphs != null) {
                            for (HSLFTextParagraph paragraph : paragraphs) {
                                String title = "";
                                if (paragraph == null) {
                                    title = "";
                                } else {
                                    title = paragraph + "";
                                }
                                String titleformate = title.replace(" ", "").replace("\n", "").replace("\r\n", "");
                                if (isInteger(titleformate) || titleformate.equals("") || titleformate.length() >= 30 || titleformate.length() <= 1|| titleformate.equals("Exceedyourexpectation")) {
                                    flag = 0;
                                    continue;
                                } else {
                                    title = title.trim().replace("\n", "").replace("\r\n", "") + "......" + slide.getSlideName();
                                    pptTitle = pptTitle + title + "\n";
                                    flag = 1;
                                    break;
                                }
                            }
                            if (flag == 1) {
                                break;
                            }

                        }
                    }
                }
            }
            return pptTitle;
        } catch (Exception e) {
            return "";
        }
    }

    public String getPptxTitles(String path) throws IOException {

        try {
            FileInputStream is = new FileInputStream(path);
            ZipSecureFile.setMinInflateRatio(-1.0d);
            XMLSlideShow ppt = new XMLSlideShow(is);
            String pptTitle = "";
            is.close();
            List<XSLFSlide> slides = ppt.getSlides();
            for (XSLFSlide slide : slides) {
                if (slide.getTitle() != null && !slide.getTitle().replace(" ", "").replace("\n", "").replace("\r\n", "").equals("") && slide.getTitle().length() <= 30 && slide.getTitle().length() > 1) {
                    pptTitle = pptTitle + slide.getTitle().replace(" ", "").replace("\n", "").replace("\r\n", "") + "......" + slide.getSlideName() + "\n";
                } else {
                    //如果幻灯片中没有设置标题，则获取每页中的第一个文本块，提出空文本和数字文本,如果标题超过30个字， 取下一个
                    for (XSLFShape shape : slide) {
                        String title = "";
                        if (shape instanceof XSLFTextShape) {
                            XSLFTextShape txShape = (XSLFTextShape) shape;
                            title = txShape.getText();
                        }
                        String titleformate = title.replace(" ", "").replace("\n", "").replace("\r\n", "");
                        if (isInteger(titleformate) || titleformate.equals("") || titleformate.length() >= 30 || titleformate.length() <= 1|| titleformate.equals("Exceedyourexpectation"))
                            continue;
                        else {
                            title =  title.trim().replace("\n", "").replace("\r\n", "") + "......" + slide.getSlideName();
                            pptTitle = pptTitle + title + "\n";
                            break;
                        }
                    }
                }

            }
            return pptTitle;
        } catch (Exception e) {
            return "";
        }
    }

    public boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    public static void main(String[] args) throws IOException, OpenXML4JException, XmlException {
        PptParser wd = new PptParser();
//        String wordVo  = wd.parseToString("D:\\002图纸\\2020_06_14\\微波\\设计提案\\微波色彩设计方案.ppt");
        StructablePptVo pptVo = wd.parse("E:\\002_Model\\003\\制药112班毕业设计\\制药112班+张建强+20114570232\\毕业设计张建强ppt.ppt");
//        wd.getPptTitles("D:\\002图纸\\2020_04_05\\建筑垃圾一体式处理装置\\作品说明书\\建筑垃圾处理装置说明书.ppt");
//        System.out.println(pptVo.getContent());
        System.out.println(pptVo.getTitles());

    }
}
